package com.gs.thunder_manage.config.systemlog;

import com.gs.thunder_manage.config.webmvc.WebUtil;
import com.gs.thunder_manage.entity.SystemLog;
import com.gs.thunder_manage.service.SystemLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User: Legolas
 * Date: 2017/12/28 0028
 */
@Aspect
public class LogAopAction {

    @Autowired
    private SystemLogService systemLogService;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    //配置接入点
    @Pointcut("execution(* com.gs.thunder_manage.web.controller..*.*(..))")
    private void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        SystemLog systemLog = new SystemLog();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String userId = (String) request.getSession().getAttribute("user_id");
        String userName = (String) request.getSession().getAttribute("user_name");
        systemLog.setUserId(userId);
        systemLog.setUserName(userName);
        String time = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date());
        systemLog.setTime(time);

        //获取系统ip
        String ip = WebUtil.getClientIp();
        systemLog.setIp(ip);

        //拦截的实体类，正在执行的controller
        Object target = pjp.getTarget();
        //拦截的方法名称，正在执行的方法
        String methodName = pjp.getSignature().getName();

        //获得注解对象类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        //获得注解中的参数类型
        Class[] parameterTypes = msig.getMethod().getParameterTypes();

        Object object = null;
        //获得被拦截的方法
        Method method = null;

        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException el) {
            logger.info("日志异常->{}",el.getMessage());
        } catch (SecurityException el) {
            logger.info("日志异常->{}",el.getMessage());
        }
        if (null != method) {
            //判断是否包含自定义注解
            if (method.isAnnotationPresent(MineLog.class)) {
                MineLog mineLog = method.getAnnotation(MineLog.class);
                systemLog.setModule(mineLog.module());
                systemLog.setMethod(mineLog.methods());
                try {
                    object = pjp.proceed();
                    systemLog.setCommit("执行成功");
                    //保存进数据库
                    systemLogService.addSystemLog(systemLog);
                } catch (Throwable e) {
                    systemLog.setCommit("执行失败");
                    //systemLogService.addSystemLog(systemLog);
                    logger.info("执行操作->{}",systemLog);
                }
            } else {
                //没有自定义注解，不需要拦截直接执行
                object = pjp.proceed();
            }
        } else {
            //没有注解，不需要拦截直接执行
            object = pjp.proceed();
        }
        return object;
    }


}
